﻿using System.Diagnostics;
using System.Runtime.Versioning;
using CommunityToolkit.Maui.Core.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui.LifecycleEvents;
using Microsoft.Maui.Platform;

namespace CommunityToolkit.Maui.Core;

/// <summary>
/// <see cref="MauiAppBuilder"/> Extensions
/// </summary>
[SupportedOSPlatform("iOS15.0")]
[SupportedOSPlatform("MacCatalyst15.0")]
[SupportedOSPlatform("Android21.0")]
[SupportedOSPlatform("Windows10.0.17763")]
[SupportedOSPlatform("Tizen6.5")]
public static class AppBuilderExtensions
{
	static readonly WeakEventManager weakEventManager = new();

	// This is an internal event used by Unit Tests to confirm when the code enters the `if (Options.ShouldUseStatusBarBehaviorOnAndroidModalPage)` block
	internal static event EventHandler ShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted
	{
		add => weakEventManager.AddEventHandler(value);
		remove => weakEventManager.RemoveEventHandler(value);
	}

	/// <summary>
	/// Initializes the .NET MAUI Community Toolkit Core Library
	/// </summary>
	/// <param name="builder"><see cref="MauiAppBuilder"/> generated by <see cref="MauiApp"/> </param>
	/// <param name="options"><see cref="Options"/></param>
	/// <returns><see cref="MauiAppBuilder"/> initialized for <see cref="CommunityToolkit.Maui.Core"/></returns>
	public static MauiAppBuilder UseMauiCommunityToolkitCore(this MauiAppBuilder builder, Action<Options>? options = null)
	{
		options?.Invoke(new Options());

		if (Options.ShouldUseStatusBarBehaviorOnAndroidModalPage)
		{

#if ANDROID
            builder.Services.AddSingleton<IDialogFragmentService, DialogFragmentService>();

			builder.ConfigureLifecycleEvents(static lifecycleBuilder =>
			{
				lifecycleBuilder.AddAndroid(static androidBuilder =>
				{
					androidBuilder.OnCreate(static (activity, _) =>
					{
						if (activity is not AndroidX.AppCompat.App.AppCompatActivity componentActivity)
						{
							Trace.WriteLine($"Unable to Modify Android StatusBar On ModalPage: Activity {activity.LocalClassName} must be an {nameof(AndroidX.AppCompat.App.AppCompatActivity)}");
							return;
						}

						if (componentActivity.GetFragmentManager() is not AndroidX.Fragment.App.FragmentManager fragmentManager)
						{
							Trace.WriteLine($"Unable to Modify Android StatusBar On ModalPage: Unable to retrieve fragment manager from {nameof(AndroidX.AppCompat.App.AppCompatActivity)}");
							return;
						}

						var dialogFragmentService = IPlatformApplication.Current?.Services.GetRequiredService<IDialogFragmentService>() 
						                            ?? throw new InvalidOperationException($"Unable to retrieve {nameof(IDialogFragmentService)}");


						fragmentManager.RegisterFragmentLifecycleCallbacks(new FragmentLifecycleManager(dialogFragmentService), false);
					});
				});
			});
#endif

			weakEventManager.HandleEvent(null, EventArgs.Empty, nameof(ShouldUseStatusBarBehaviorOnAndroidModalPageOptionCompleted));
		}

		return builder;
	}
}